package cc.rengu.igas.channel.cups.core.realize.impl;

import cc.rengu.igas.channel.cups.common.constant.CupsConfigConstant;
import cc.rengu.igas.channel.cups.core.realize.CupsMacService;
import cc.rengu.oltp.service.common.constant.TreeNodeConstant;
import cc.rengu.oltp.service.common.entity.KeyInfo;
import cc.rengu.oltp.service.common.entity.SysParam;
import cc.rengu.oltp.service.realize.SysParamService;
import cc.rengu.oltp.service.realize.impl.SysParamServiceImpl;
import cc.rengu.oltp.utility.util.ByteUtil;
import cc.rengu.oltp.utility.util.MACUtil;
import cc.rengu.oltp.utility.util.SM4Util;
import cc.rengu.oltp.utility.util.XmlTreeUtil;
import cc.rengu.utility.log.RgLog;
import cc.rengu.utility.log.RgLogger;

/**
 * mac服务实现
 *
 * @author Gendb
 */
@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
public class CupsMacServiceImpl implements CupsMacService {
    private RgLogger rgLog = RgLog.getLogger(this.getClass().getName());

    /**
     * 对称密钥 3DES算法，国际
     */
    private static final String DES3 = "3DES";
    /**
     * 对称密钥 SM4算法。国密
     */
    private static final String SM4 = "SM4";

    @Override
    public String genMacString(KeyInfo keyInfo, String macBlock) throws Exception {
        String encType = "0";
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_ENC_TYPE);
        if (sysParam != null) {
            encType = sysParam.getParamValue();
        }
        if ("0".equals(encType)) {
            rgLog.debug("使用软加密,算法类型:<{}>,", keyInfo.getAlgorithmType());
            if (DES3.equals(keyInfo.getAlgorithmType())) {
                return MACUtil.gen3DesMac(keyInfo.getKeyValue(), macBlock);
            } else {
                return MACUtil.genSm4Mac(keyInfo.getKeyValue(), macBlock);
            }
        } else {
            //硬加密
            rgLog.info("使用硬加密开始验证mac");
//            List<SysParam> sysParamList = sysParamService.getSysParamInfo(instId, ShareParamConstant.ENCRYPROT_PARAM);
//            if (sysParamList.size() == 0) {
//                throw new Exception("获取加密加参数失败");
//            }
//            String serverIp = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_SERVER)).findFirst().get().getParamValue();
//            int serverPort = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_PORT)).findFirst().get().getParamValue());
//            int timeOut = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_TIME_OUT)).findFirst().get().getParamValue());
//            int connType = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_CONN_TYPE)).findFirst().get().getParamValue());
//            int headMsgLen = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_LEN)).findFirst().get().getParamValue());
//            int connNum = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_CONN_NUM)).findFirst().get().getParamValue());
//            String designId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_MAC_DESIGN_ID)).findFirst().get().getParamValue();
//            String nodeId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_MAC_NODE_ID)).findFirst().get().getParamValue();
//            String keyModelId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_MAC_KEY_MODEL_ID)).findFirst().get().getParamValue();
//            String appId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_APP_ID)).findFirst().get().getParamValue();
//            if (macBlock.endsWith(" ")) {
//                macBlock = macBlock.substring(0, macBlock.length() - 1);
//            }
//            HisuTSSCAPI tsscObj = new HisuTSSCAPI(serverIp, serverPort, timeOut, headMsgLen, connNum, connType, appId);
//            HisuTSSCAPIResult hisuTSSCAPIResult = tsscObj.calculateDataMACOfUPayBySpecKey(designId, nodeId, keyModelId, 1, macBlock);
//            int retCode = hisuTSSCAPIResult.getErrCode();
//            if (retCode < 0) {
//                rgLog.error("====MAC生成失败====");
//            } else {
//                rgLog.info("====MAC生成成功====");
//
//                return hisuTSSCAPIResult.getMAC();
//            }
            return null;
        }
    }

    @Override
    public boolean verifyMacString(KeyInfo keyInfo, String mac, String macBlock) throws Exception {
        String encType = "0";
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_ENC_TYPE);
        if (sysParam != null) {
            encType = sysParam.getParamValue();
        }
        if ("0".equals(encType)) {
            //软加密 实现
            rgLog.debug("使用软加密,算法类型:<{}>,", keyInfo.getAlgorithmType());
            if ("3DES".equals(keyInfo.getAlgorithmType())) {
                return MACUtil.verify3DesMac(keyInfo.getKeyValue(), macBlock, mac);
            } else {
                return MACUtil.verifySm4Mac(keyInfo.getKeyValue(), macBlock, mac);
            }
        } else {
            //硬加密
            rgLog.info("使用硬加密开始验证mac");
//            List<SysParam> sysParamList = sysParamService.getSysParamInfo(instId, ShareParamConstant.ENCRYPROT_PARAM);
//            if (sysParamList.size() == 0) {
//                throw new Exception("获取加密加参数失败");
//            }
//            String serverIp = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_SERVER)).findFirst().get().getParamValue();
//            int serverPort = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_PORT)).findFirst().get().getParamValue());
//            int timeOut = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_TIME_OUT)).findFirst().get().getParamValue());
//            int connType = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_CONN_TYPE)).findFirst().get().getParamValue());
//            int headMsgLen = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_LEN)).findFirst().get().getParamValue());
//            int connNum = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_CONN_NUM)).findFirst().get().getParamValue());
//            String designId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_MAC_DESIGN_ID)).findFirst().get().getParamValue();
//            String nodeId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_MAC_NODE_ID)).findFirst().get().getParamValue();
//            String keyModelId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_MAC_KEY_MODEL_ID)).findFirst().get().getParamValue();
//            String appId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_APP_ID)).findFirst().get().getParamValue();
//            //macblock 去最后一位空格
//            if (macBlock.endsWith(" ")) {
//                macBlock = macBlock.substring(0, macBlock.length() - 1);
//            }
//            mac = new String(StringUtil.hexStringToBinary(mac), CupsParamConstant.GB18030);
//            HisuTSSCAPI tsscObj = new HisuTSSCAPI(serverIp, serverPort, timeOut, headMsgLen, connNum, connType, appId);
//            rgLog.info("MAC_BLOCK:{}", macBlock);
//            rgLog.info("MAC:{}", mac);
//            HisuTSSCAPIResult hisuTSSCAPIResult = tsscObj.verifyDataMACOfUPayBySpecKey(designId, nodeId, keyModelId, 1, macBlock, mac);
//            int retCode = hisuTSSCAPIResult.getErrCode();
//            if (retCode < 0) {
//                rgLog.error("====MAC校验失败{}====", retCode);
//            } else {
//                rgLog.info("====MAC校验成功====");
//                return true;
//            }
//            return false;
        }
        return false;
    }

    @Override
    public boolean verifyReSetKeyMacString(KeyInfo keyInfo, String mac, String macBlock) throws Exception {
        String encType = "0";
        XmlTreeUtil xmlTreeUtil = new XmlTreeUtil();
        String instId = xmlTreeUtil.getXmlTreeStringValue(TreeNodeConstant.INST_ID);
        SysParamService sysParamService = new SysParamServiceImpl();
        SysParam sysParam = sysParamService.getSysParamInfo(instId, CupsConfigConstant.CUPS_CONF_NODE, CupsConfigConstant.CUPS_ENC_TYPE);
        if (sysParam != null) {
            encType = sysParam.getParamValue();
        }
        if ("0".equals(encType)) {
            rgLog.debug("使用软加密,算法类型:<{}>,", keyInfo.getAlgorithmType());
            if (DES3.equals(keyInfo.getAlgorithmType())) {
                return MACUtil.verify3DesMac(keyInfo.getKeyValue(), macBlock, mac);
            } else {
                String macTmp = MACUtil.genSm4Mac(keyInfo.getKeyValue(), macBlock).substring(0, 8);
                String checkValue = ByteUtil.bytesToHexString(SM4Util.genCheckValue(ByteUtil.hexStringToByte(keyInfo.getKeyValue()))).substring(0, 8);
                String macGen = macTmp + checkValue;
                if (mac.equals(macGen)) {
                    return true;
                } else {
                    rgLog.error("key=[{}]", keyInfo.getKeyValue());
                    rgLog.error("src macValue=[{}], gen macValue=[{}]", mac, macGen);
                    return false;
                }

            }
        } else {
            /*硬加密，需要自己客户化*/
            rgLog.info("使用硬加密开始验证mac");
//            List<SysParam> sysParamList = sysParamService.getSysParamInfo(instId, ShareParamConstant.ENCRYPROT_PARAM);
//            if (sysParamList.size() == 0) {
//                throw new Exception("获取加密机参数失败");
//            }
//            String serverIp = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_SERVER)).findFirst().get().getParamValue();
//            int serverPort = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_PORT)).findFirst().get().getParamValue());
//            int timeOut = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_TIME_OUT)).findFirst().get().getParamValue());
//            int connType = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_CONN_TYPE)).findFirst().get().getParamValue());
//            int headMsgLen = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_LEN)).findFirst().get().getParamValue());
//            int connNum = Integer.parseInt(sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_CONN_NUM)).findFirst().get().getParamValue());
//            String appId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_APP_ID)).findFirst().get().getParamValue();
//
//            String designId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_MAC_DESIGN_ID)).findFirst().get().getParamValue();
//            String nodeId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_MAC_NODE_ID)).findFirst().get().getParamValue();
//            String keyModelId = sysParamList.stream().filter(item -> item.getParamKey().equals(ShareParamConstant.ENCRYPROT_MAC_KEY_MODEL_ID)).findFirst().get().getParamValue();
//
//            //macblock 去最后一位空格
//            if (macBlock.endsWith(" ")) {
//                macBlock = macBlock.substring(0, macBlock.length() - 1);
//            }
//            mac = new String(StringUtil.hexStringToBinary(mac), CupsParamConstant.GB18030);
//            HisuTSSCAPI tsscObj = new HisuTSSCAPI(serverIp, serverPort, timeOut, headMsgLen, connNum, connType, appId);
//            rgLog.info("MAC_BLOCK:{}", macBlock);
//            rgLog.info("MAC:{}", mac);
//            HisuTSSCAPIResult hisuTSSCAPIResult = tsscObj.verifyDataMACOfUPayBySpecKey(designId, nodeId, keyModelId, 1, macBlock, mac);
//            int retCode = hisuTSSCAPIResult.getErrCode();
//            if (retCode < 0) {
//                rgLog.error("====MAC校验失败{}====", retCode);
//            } else {
//                rgLog.info("====MAC校验成功====");
//                return true;
//            }
            return false;
        }
    }
}
